package qianting.news.gateway.filter;

import cn.hutool.core.lang.Assert;
import com.alibaba.nacos.common.utils.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import qianting.news.common.entity.AuthUser;
import qianting.news.common.enums.AppHttpCodeEnum;
import qianting.news.common.utils.AppThreadLocalUtil;
import qianting.news.gateway.entity.State;
import qianting.news.gateway.feign.AuthClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

@Order(-1)
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter {

    @Autowired
    private AuthClient authClient;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取请求的路径
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().value();

        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        String uri=route.getUri().toString();

        if(path.contains("login")||path.contains("register")){
            //放行
            return chain.filter(exchange);
        }

        if(path.contains("doc.html")||path.contains("swagger")||path.contains("webjars")||path.contains("api-docs")){
            //knife4j放行
            return chain.filter(exchange);
        }

        log.info("请求request信息,path="+uri+exchange.getRequest().getPath());

        HttpHeaders headers = exchange.getRequest().getHeaders();
        String token = headers.getFirst("token");
        Assert.notNull(token, AppHttpCodeEnum.NEED_LOGIN.getErrorMessage());
        //获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        //远程校验token
        State state = authClient.verify(token);
        if(state.getCode()==200){
            //放行
            HashMap<String,Object> claims = (HashMap) state.getData();
            //将解析获得的用户信息存入header中
            request.mutate().headers(header->{
                header.add("userId",claims.get("userId")+"");
                header.add("username",(String) claims.get("username"));
            }).build();
//            exchange.mutate().request(request).build();//重置header
            return chain.filter(exchange);
        }
        //拦截
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        ServerHttpResponse response = exchange.getResponse();
        Map<String, Object> map = new HashMap<>();
        map.put("msg", AppHttpCodeEnum.TOKEN_INVALID);
        map.put("code", "403");
        byte[] bytes = JacksonUtils.toJsonBytes(map);
        DataBuffer buffer = response.bufferFactory().wrap(bytes);
        //结束处理
        return response.writeWith(Mono.just(buffer));
//        return exchange.getResponse().setComplete();
    }

}
